﻿namespace BEGDC.CC.Web.EZVisit.Controls
{
    #region Using Directives

    using System;
    using System.Data;
    using System.Linq;
    using System.Web.UI.WebControls;
    using ASBCC.Business;
    using ASBCC.Database.Entity;
    using ASBCC.Database.Service;
    using ASBCC.Workflow.Client;
    using ASBCC.Workflow.K2Manager;
    using BL.Common;
    using Utility.Castle;
    using Utility.Extensions;

    #endregion

    public partial class EZVRequestContract : EZVRequestBaseControl
    {
        protected bool CanShowContractDetails
        {
            get
            {
                if (this.EZVisitApplication == null || this.EZVisitApplication.FNCController == null)
                {
                    return false;
                }

                bool canShowInfo = ValueIncludes(this.EZVisitApplication.FNCController, this.CurrentUser);
                canShowInfo |= ValueIncludes(this.EZVisitApplication.CODPPCheckPersonNameEN, this.CurrentUser);

                return canShowInfo;
            }
        }

        protected override bool NeedValidate
        {
            get
            {
                return this.Visible;
            }
        }

        protected override void SetVisibility()
        {
            base.SetVisibility();

            bool visible = this.Editable ? this.edt_SalesContract.SelectedValue.Equals("1") : this.vw_SalesContract.Text.Equals("Yes");

            this.lblInfo.Visible = this.secContract2.Visible = visible;
            this.secContract5.Visible = this.secContract6.Visible=this.secContract7.Visible = visible;
            this.secContract3.Visible = this.secContract4.Visible = !visible;
            
            if (this.Editable)
            {
                string productsRelatedSelectedValue = this.edt_ProductsRelated.SelectedValue;
                switch (productsRelatedSelectedValue)
                {
                    case "0":
                        this.secContract6.Visible = true;
                        this.secContract7.Visible = false;
                        this.edt_rfv4.Enabled = true;
                        this.edt_rfv5.Enabled = false;
                        break;
                    case "2":
                        this.secContract6.Visible = false;
                        this.secContract7.Visible = true;
                        this.edt_rfv4.Enabled = false;
                        this.edt_rfv5.Enabled = true;
                        break;
                    default:
                        this.secContract6.Visible = this.secContract7.Visible = false;
                        this.edt_rfv4.Enabled = this.edt_rfv5.Enabled = false;
                        break;
                }
            }
            else
            {
                string productsRelatedText = this.vw_ProductsRelated.Text;
                switch (productsRelatedText)
                {
                    case "NO":
                        this.secContract6.Visible = true;
                        this.secContract7.Visible = false;
                        this.edt_rfv4.Enabled = false;
                        this.edt_rfv5.Enabled = false;
                        break;
                    case "OTHERS":
                        this.secContract6.Visible = false;
                        this.secContract7.Visible = true;
                        this.edt_rfv4.Enabled = false;
                        this.edt_rfv5.Enabled = false;
                        break;
                    default:
                        this.secContract6.Visible = this.secContract7.Visible = false;
                        this.edt_rfv4.Enabled = this.edt_rfv5.Enabled = false;
                        break;
                }

            }

            this.secLegend.Visible = this.CanShowContractDetails;
        }

        protected override void SetViewData()
        {
            if (this.EZVisitApplication == null)
            {
                return;
            }

            for (int i = 3; i < 11; i++)
            {
                this.dgContract.Columns[i].Visible = this.CanShowContractDetails;
            }

            this.dgContract.Columns[11].Visible = this.Editable;

            this.pnlContract.Attributes["style"] = string.Format("width:{0}%", this.CanShowContractDetails ? 99 : 80);

            bool isFnc = this.EZVisitApplication.ProcessStatus.IsNotNullOrWhiteSpace() && !this.EZVisitApplication.ProcessStatus.Equals(ProcessStatusConsts.Withdrawn);
            isFnc &= this.EZVisitApplication.CurrentStep.IsNotNullOrWhiteSpace() && ValueIncludes(this.EZVisitApplication.CurrentStep, EZVisitActivityNameConsts.FNC_Controller);

            this.Editable &= !isFnc;

            if (this.Editable)
            {
                this.edt_SalesContract.SelectedValue = this.EZVisitApplication.IsInSalesContract != null && !this.EZVisitApplication.IsInSalesContract.Value ? "0" : "1";
                this.edt_ProductsRelated.SelectedValue = this.EZVisitApplication.IsInProducstSold.GetValueOrDefault(1).ToString();

                if (this.EZVisitApplication.TotalCost != null)
                {
                    this.edt_Cost.Text = this.EZVisitApplication.TotalCost.Value.ToString();
                }
                this.edt_CostCenter.Text = this.EZVisitApplication.CostCenter;
                this.edt_Products.Text = this.EZVisitApplication.ProducstSold;
                this.edt_others.Text = this.EZVisitApplication.ProducstOther;
            }
            else
            {
                this.vw_SalesContract.Text = this.EZVisitApplication.IsInSalesContract != null && !this.EZVisitApplication.IsInSalesContract.Value ? "No" : "Yes";
                string IsInProducstSold = "YES";
                if (this.EZVisitApplication.IsInProducstSold.Value == 0)
                    IsInProducstSold = "NO";
                else if (this.EZVisitApplication.IsInProducstSold.Value == 1)
                    IsInProducstSold = "YES";
                else
                    IsInProducstSold = "OTHERS";

                this.vw_ProductsRelated.Text = IsInProducstSold;

                if (this.EZVisitApplication.TotalCost != null)
                {
                    this.vw_Cost.Text = "¥" + this.EZVisitApplication.TotalCost.Value;
                }

                this.vw_CostCenter.Text = this.EZVisitApplication.CostCenter;
                this.vw_Products.Text = this.EZVisitApplication.ProducstSold;
                this.vw_others.Text = this.EZVisitApplication.ProducstOther;
            }

            if (this.EZVisitApplication.TotalCostEUR != null)
            {
                this.hidCostEuro.Value = this.lbCostEuro.Text = this.EZVisitApplication.TotalCostEUR.Value.ToString();
                this.lbExchangeRate1.Text = this.EZVisitApplication.ExchangeRate.Value.ToString();
            }

            this.lbExchangeRate.Text = this.lbExchangeRate1.Text = this.EZVisitApplication.ExchangeRate == null ? GetExchangeRate().ToString() : this.EZVisitApplication.ExchangeRate.Value.ToString();

            this.BindContractInfo();
        }

        protected override bool Validate(out string error)
        {
            error = string.Empty;

            if (this.CurrentActionType.IsNotNullOrWhiteSpace() && this.dgContract.Visible)
            {
                switch (this.CurrentActionType)
                {
                    case K2ActionType.Submit:
                    case K2ActionType.Resubmit:
                        if (this.dgContract.Items.Count == 0)
                        {
                            error = @"- [Contract Info.] Contracts were not provided.\n";
                        }
                        break;
                    case K2ActionType.Approve:
                        error = (from DataGridItem i in this.dgContract.Items where i.Cells[7].Text.Replace("&nbsp;", string.Empty).Trim().Length == 0 select i).Aggregate(error, (current, i) => current + string.Format(@"- Contract No.[{0}]: Cost Center was not provided. \n", i.Cells[1].Text));

                        if (error.Length == 0)
                        {
                            error = (from DataGridItem i in this.dgContract.Items where i.Cells[9].Text.Replace("&nbsp;", string.Empty).Trim().Length == 0 select i).Aggregate(error, (current, i) => current + string.Format(@"- Contract No.[{0}]: WBSE was not provided. \n", i.Cells[1].Text));
                        }

                        break;
                }
            }

            return error.Length == 0;
        }

        public override void Save(EZVisitApplicationTableEntity app)
        {
            if (app == null)
            {
                return;
            }

            if (!this.CurrentActionType.Equals(K2ActionType.Withdraw) && !this.CurrentActionType.Equals(K2ActionType.Approve))
            {
                app.IsInSalesContract = this.edt_SalesContract.SelectedValue.Equals("1");
                app.CostCenter = !app.IsInSalesContract.Value ? this.edt_CostCenter.Text : string.Empty;
                app.TotalCost = new decimal?();
                app.TotalCostEUR = new decimal?();
                app.ExchangeRate = Convert.ToDouble(this.lbExchangeRate.Text);

                decimal cost;

                if (decimal.TryParse(app.IsInSalesContract.Value ? this.lbContractSum.Text : this.edt_Cost.Text, out cost))
                {
                    app.TotalCost = cost;
                    app.TotalCostEUR = Convert.ToDecimal(app.IsInSalesContract.Value ? this.lbContractSumEuro.Text : this.hidCostEuro.Value);
                }

                app.IsInProducstSold = int.Parse(this.edt_ProductsRelated.SelectedValue);
                app.ProducstSold = app.IsInSalesContract.Value && app.IsInProducstSold.Value == 0 ? this.edt_Products.Text : string.Empty;
                app.ProducstOther = app.IsInSalesContract.Value && app.IsInProducstSold.Value == 2 ? this.edt_others.Text : string.Empty;
            }

            base.Save(app);
            this.SaveContracts();
        }

        private void SaveContracts()
        {
            var dt = this.Session[Common.EZVRequestContract.SessionKey + this.SessionKey] as DataTable;

            if (dt == null || dt.Rows.Count == 0)
            {
                return;
            }

            // If no sales contracts
            if (this.edt_SalesContract.SelectedValue.Equals("0"))
            {
                foreach (DataRow row in dt.Rows)
                {
                    row["IsEnabled"] = false;
                }
            }

            var contracts = dt.ToEntities<EZVisitContractItemTableEntity>();

            foreach (EZVisitContractItemTableEntity contract in contracts)
            {
                if (this.CurrentActionType.Equals(K2ActionType.Withdraw))
                {
                    contract.WBSE = contract.WBSED = null;
                    contract.LegalEntity = contract.CostCenter = null;
                    contract.LegalEntityID = new int?();
                    contract.WBSP = contract.WBSPD = null;
                    contract.InvoiceHeader = null;
                    contract.VisitCost = contract.EstimatedTotalCost = contract.ApplicantCost;
                    contract.TrainingCost = 0;

                    var d = new decimal ?();
                    contract.OnGoingAmount = d;
                    contract.TrainingOnGoingAmount = d;
                    contract.VisitOnGoingAmount = d;

                    EZVisitContractItemManager.Update(contract);
                }
                else
                {
                    contract.AppID = this.EZVisitApplication.AppID;

                    if (contract.ContractItemIDIsNull())
                    {
                        EZVisitContractItemManager.Insert(contract);
                    }
                    else
                    {
                        EZVisitContractItemManager.Update(contract);
                    }
                }
            }

            this.Session[Common.EZVRequestContract.SessionKey + this.SessionKey] = SetRowID(this.BuildContractTable());
            this.BindContractInfo();
        }

        public void BindContractInfo()
        {
            if (this.EZVisitApplication == null || !this.Visible)
            {
                return;
            }

            var dt = this.Session[Common.EZVRequestContract.SessionKey + this.SessionKey] as DataTable;

            if (dt == null)
            {
                this.Session[Common.EZVRequestContract.SessionKey + this.SessionKey] = dt = SetRowID(this.BuildContractTable());
            }

            this.dgContract.DataSource = dt;
            this.dgContract.DataBind();

            decimal sum = CalculateSum(dt);

            this.lbContractSum.Text = sum.ToString("0.00");

            decimal rate = Convert.ToDecimal(this.lbExchangeRate.Text);

            this.lbContractSumEuro.Text = (sum / rate).ToString("0.00");
        }

        private DataTable BuildContractTable()
        {
            var dt = QueryExtensions.CreateDataTableSchemaFromEntity(typeof(EZVisitContractItemTableEntity));

            int appId = this.EZVisitApplication.AppID.GetValueOrDefault(0);

            if (appId > 0)
            {
                if (this.CanShowContractDetails)
                {
                    dt = new EZVisitBusiness().GetContractsByAppId(appId);
                }
                else
                {
                    string condition = string.Format("AppID='{0}' and IsEnabled=1", appId);
                    dt = EZVisitContractItemManager.SelectByCondition(condition).Tables[0];
                }
            }

            if (!this.CanShowContractDetails)
            {
                dt.Columns.Add("VisitBalance");
                dt.Columns.Add("TrainingBalance");
                dt.Columns.Add("Balance");
            }

            dt.Columns.Add("RowId");
            return dt;
        }

        #region Events

        protected void dgContract_DeleteCommand(object source, DataGridCommandEventArgs e)
        {
            int rowId = Convert.ToInt32(e.Item.Cells[0].Text);

            var dt = (DataTable)this.Session[Common.EZVRequestContract.SessionKey + this.SessionKey];

            DataRow row = dt.Rows[rowId - 1];

            // Newly added contract?
            if (row.IsNull("ContractItemID"))
            {
                dt.Rows.Remove(row);
            }
            else
            {
                row["IsEnabled"] = false;
                row["UpdateAt"] = DateTime.Now;
                row["UpdateBy"] = this.CurrentUser;
            }

            this.Session[Common.EZVRequestContract.SessionKey + this.SessionKey] = SetRowID(dt);

            this.BindContractInfo();
        }

        protected void dgContract_ItemDataBound(object sender, DataGridItemEventArgs e)
        {
            if ((e.Item.ItemType != ListItemType.Item) && (e.Item.ItemType != ListItemType.AlternatingItem))
            {
                return;
            }

            var cell = e.Item.Cells[11];

            var btnEdit = (ImageButton)cell.FindControl("btnEdit");
            btnEdit.Attributes.Add("onclick", "return openContractPanel('" + e.Item.Cells[0].Text + "');");

            var btnDelete = (ImageButton)cell.FindControl("btnDelete");
            btnDelete.Attributes.Add("onclick", "return confirm('Are you sure to delete this item?');");

            btnDelete.Visible = (this.EZVisitApplication.ProcessStatus.IsNotNullOrWhiteSpace() && this.EZVisitApplication.ProcessStatus.Equals(ProcessStatusConsts.Withdrawn)) || !ValueIncludes(this.EZVisitApplication.CurrentStep, EZVisitActivityNameConsts.FNC_Controller);
        }

        protected void rblProductsRelated_SelectedIndexChanged(object sender, EventArgs e)
        {
            string productsRelatedSelectedValue = this.edt_ProductsRelated.SelectedValue;
            switch (productsRelatedSelectedValue)
            {
                case "0":
                    this.secContract6.Visible = true;
                    this.secContract7.Visible = false;
                    this.edt_rfv4.Enabled = this.edt_Products.Visible = this.Editable;
                    this.edt_rfv5.Enabled = false;
                    break;
                case "2":
                    this.secContract6.Visible = false;
                    this.secContract7.Visible = true;
                    this.edt_rfv4.Enabled = false;
                    this.edt_rfv5.Enabled = this.edt_others.Visible = this.Editable;
                    break;
                default:
                    this.secContract6.Visible = this.secContract7.Visible = false;
                    this.edt_rfv4.Enabled = this.edt_rfv5.Enabled = false;
                    break;
            }

        }

        protected void rblSalesContract_SelectedIndexChanged(object sender, EventArgs e)
        {
            bool visible = this.edt_SalesContract.SelectedValue.Equals("1");
            this.secContract2.Visible = visible;
            this.secContract5.Visible = visible;
            this.lblInfo.Visible = visible;
            this.secContract6.Visible = visible & this.edt_ProductsRelated.SelectedValue.Equals("0");
            this.edt_rfv4.Enabled = this.edt_Products.Visible = this.secContract6.Visible & this.Editable;
            this.secContract7.Visible = visible & this.edt_ProductsRelated.SelectedValue.Equals("2");
            this.edt_rfv5.Enabled = this.edt_others.Visible = this.secContract7.Visible & this.Editable;

            this.secContract3.Visible = !visible;
            this.secContract4.Visible = !visible;

            decimal sum;

            if (decimal.TryParse(this.edt_Cost.Text, out sum))
            {
                decimal rate = Convert.ToDecimal(this.lbExchangeRate1.Text);

                this.lbCostEuro.Text = (sum / rate).ToString("0.00");
            }

            if (this.EZVisitApplication != null)
            {
                this.EZVisitApplication.IsInSalesContract = visible;
            }
        }

        #endregion

        #region Helpers

        private static double GetExchangeRate()
        {
            var utilityService = (IUtility)AppContainer.Instance[ServiceConst.UtilityService];
            var rate = utilityService.GetCurrencyExchange();
            return rate.Exchange;
        }

        private static decimal CalculateSum(DataTable dt)
        {
            decimal sum = 0;
            if (dt != null)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    sum += Convert.ToDecimal(dt.Rows[i]["EstimatedTotalCost"]);
                }
            }

            return sum;
        }

        private static DataTable SetRowID(DataTable table)
        {
            if (table != null && table.Rows.Count > 0)
            {
                for (int i = 1; i <= table.Rows.Count; i++)
                {
                    table.Rows[i - 1]["RowId"] = i.ToString();
                }
            }
            return table;
        }

        private static bool ValueIncludes(string src, string dest)
        {
            src = ";" + src + ";";
            dest = ";" + dest + ";";
            return src.IndexOf(dest, StringComparison.InvariantCultureIgnoreCase) != -1;
        }

        #endregion
    }
}